﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace SuspectPhoto
{



    public delegate void GetRealDataCallBack(long lRealHandle, int dwDataType, byte[] pBuffer, int dwBufSize, int dwUser);

    public delegate void TextBoxInvokeHandle();

    public partial class MonitorFrm : Form
    {
        public IList<ScreenInfo> mScreenInfos;

        public string strHeadImagePath; //打开图片的路径

        private Video mFocusVideo;

        //public IList<CameraConfig> mCameraConfigs;

        //public IList<Panel> mScreens=new List<Panel>();

        public MonitorFrm()
        {
            InitializeComponent();

            mScreenInfos = ScreenInfo.GetScreenInfos();
            AddVideos();
            Load += MonitorFrm_Load;
            Resize += MonitorFrm_Resize;
            panelScreen.Resize += panelScreen_Resize;
            pictureBox1.Resize += pictureBox1_Resize;

            vedioPic1.Visible = false;
            vedioPic2.Visible = false;
            vedioPic3.Visible = false;
            vedioPic4.Visible = false;
            vedioPic5.Visible = false;
        }

        void pictureBox1_Resize(object sender, EventArgs e)
        {
            pictureBox1.Size = new Size(panelScreen.Width - 100, 80);
            pictureBox1.Location = new Point(0, panelScreen.Size.Height + toolStrip1.Height + 5);
            btnSave.Location = new Point(125, panelScreen.Height + 50);
            btnPrint.Location = new Point(230, panelScreen.Height + 50);
            btnRedo.Location = new Point(335, panelScreen.Height + 50);
            btnTakePhoto.Location = new Point(20, panelScreen.Height + 50);
        }

        void MonitorFrm_Resize(object sender, EventArgs e)
        {
            panelScreen.Size = new Size(ClientSize.Width - 15, (int)(ClientSize.Width / mScreenInfos.Count() / ScreenInfo.AspectRatio) + 202);
            panelScreen.Location = new Point(0, toolStrip1.Height);

            uppanelline.Size = new Size(panelScreen.Size.Width, 1);
            downpanelline.Size = new Size(panelScreen.Size.Width, 1);
            uppanelline.Location = new Point(0, toolStrip1.Height + (int)(panelScreen.Size.Height * ScreenInfo.UpLineLimit / 100));

            btnUpLineUp.Location = new Point(panelScreen.Width + 1, uppanelline.Location.Y - btnUpLineUp.Height - 1);
            btnUpLineDown.Location = new Point(panelScreen.Width + 1, uppanelline.Location.Y + 1);

            downpanelline.Location = new Point(0, toolStrip1.Height + panelScreen.Size.Height - (int)(panelScreen.Size.Height * ScreenInfo.DownLineLimit / 100));

            btnDownLineUp.Location = new Point(panelScreen.Width + 1, downpanelline.Location.Y - btnDownLineUp.Height - 1);

            btnDownLineDown.Location = new Point(panelScreen.Width + 1, downpanelline.Location.Y + 1);

            pictureBox1.Size = new Size(panelScreen.Width - 50, 80);
            pictureBox1.Location = new Point(0, panelScreen.Size.Height + toolStrip1.Height + 7);
            btnSave.Location = new Point(125, panelScreen.Height + 50);
            btnPrint.Location = new Point(230, panelScreen.Height + 50);
            btnRedo.Location = new Point(335, panelScreen.Height + 50);
            btnTakePhoto.Location = new Point(20, panelScreen.Height + 50);
            btnTop.Location = new Point(pictureBox1.Width + btnSave.Width / 2 + 2, pictureBox1.Location.Y + 10);
            btnBottom.Location = new Point(pictureBox1.Width + btnSave.Width / 2 + 2, btnTop.Location.Y + btnTop.Height + 10);
            btnLeft.Location = new Point(pictureBox1.Width + 3, btnTop.Location.Y + btnTop.Height / 2 + 1);
            btnRight.Location = new Point(pictureBox1.Width + btnLeft.Width * 2 + 15, btnTop.Location.Y + btnTop.Height / 2 + 1);
            txtMsg.Size = new Size(ClientSize.Width, ClientSize.Height - toolStrip1.Height - panelScreen.Height - pictureBox1.Height - 10);
            txtMsg.Location = new Point(0, pictureBox1.Location.Y + 10);
        }

        void panelScreen_Resize(object sender, EventArgs e)
        {
            ItemReSize();
        }


        void MonitorFrm_Load(object sender, EventArgs e)
        {

            panelScreen.BorderStyle = BorderStyle.FixedSingle;

            txtMsg.ReadOnly = true;
            txtMsg.ScrollBars = ScrollBars.Vertical;

            btnTop.Click += btnMove_Click;
            btnLeft.Click += btnMove_Click;
            btnRight.Click += btnMove_Click;
            btnBottom.Click += btnMove_Click;

            MonitorFrm_Resize(this, null);

            //DrawLine();

            //panelScreen.Size = new Size(ClientSize.Width, (int)(ClientSize.Width / mScreenInfos.Count() / ScreenInfo.AspectRatio) + 2);

            GetVideo();
        }

        private void DrawLine()
        {

        }

        private void AddVideos()
        {

            foreach (ScreenInfo si in mScreenInfos)
            {
                Panel pilot = new Panel();
                this.Controls.Add(pilot);

                si.Video = new Video(ScreenInfo.ScreenScale, pilot);
                si.Video.Margin = new Padding(0);
                //si.Video.Visible = false;
                si.Video.VideoPanel.Click += VideoPanel_Click;

                panelScreen.Controls.Add(si.Video);
            }
        }

        private void ItemReSize()
        {
            try
            {
                int itemCount = mScreenInfos.Count();

                int itemWidth = GetItemWidth();

                int itemHeight = GetItemHeight();

                vedioPic1.Size = new Size(itemWidth, itemHeight);
                vedioPic1.Location = new Point(0, 0);
                vedioPic2.Size = new Size(itemWidth, itemHeight);
                vedioPic2.Location = new Point(itemWidth, 0);
                vedioPic3.Size = new Size(itemWidth, itemHeight);
                vedioPic3.Location = new Point(itemWidth * 2, 0);
                vedioPic4.Size = new Size(itemWidth, itemHeight);
                vedioPic4.Location = new Point(itemWidth * 3, 0);
                vedioPic5.Size = new Size(itemWidth, itemHeight);
                vedioPic5.Location = new Point(itemWidth * 4, 0);
                for (int i = 0; i < mScreenInfos.Count; i++)
                {
                    mScreenInfos[i].Video.Size = new Size(itemWidth, itemHeight);


                    mScreenInfos[i].Video.Pilot.Size = new Size((int)(mScreenInfos[i].Video.Width * 0.8), 2);
                    if (i == 0)
                    {
                        mScreenInfos[i].Video.Location = new Point(0, 0);
                    }
                    else
                    {
                        mScreenInfos[i].Video.Location = new Point(mScreenInfos[i - 1].Video.Right, 0);
                    }
                    mScreenInfos[i].Video.Pilot.Size = new Size((int)(mScreenInfos[i].Video.Width * 0.8), 2);
                    mScreenInfos[i].Video.Pilot.Location = new Point(mScreenInfos[i].Video.Location.X + (mScreenInfos[i].Video.Width - mScreenInfos[i].Video.Pilot.Width) / 2, panelScreen.Location.Y + panelScreen.Height + 2);
                }

            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        void VideoPanel_Click(object sender, EventArgs e)
        {
            mFocusVideo = (sender as Panel).Parent as Video;

            foreach (ScreenInfo si in mScreenInfos)
            {
                si.Video.Pilot.Hide();
            }

            mFocusVideo.Pilot.Show();
        }


        private int GetItemWidth()
        {
            return panelScreen.ClientSize.Width / mScreenInfos.Count();
        }

        private int GetItemHeight()
        {
            return (int)(GetItemWidth() / ScreenInfo.AspectRatio) + 200;
            //return GetItemWidth() * 2;
        }


        private void GetVideo()
        {

            try
            {
                bool isSuccess = CameraDevice.GT_DEV_Init();

                foreach (ScreenInfo si in mScreenInfos)
                {

                    si.AsyncPlay(VideoPlayCallBack);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void VideoPlayCallBack(bool isSuccess, string msg)
        {
            if (txtMsg.InvokeRequired)
            {
                txtMsg.Invoke(new Action<string>(DisplayText), msg);
            }
            else
            {
                DisplayText(msg);
            }

        }

        private void DisplayText(string msg)
        {
            txtMsg.Text += msg;
            txtMsg.Text += Environment.NewLine;
            txtMsg.Text += Environment.NewLine;
        }

        //上下左右调整位置按钮事件
        private void btnMove_Click(object sender, EventArgs e)
        {
            if (mFocusVideo == null)
                return;


            Button btn = sender as Button;

            if (btn == btnTop)
            {
                mFocusVideo.MoveTop();
            }
            else if (btn == btnBottom)
            {
                mFocusVideo.MoveBottom();
            }
            else if (btn == btnLeft)
            {
                mFocusVideo.MoveLeft();
            }
            else if (btn == btnRight)
            {
                mFocusVideo.MoveRight();
            }
        }

        //截取图像按钮事件
        private void btnPhoto_Click_1(object sender, EventArgs e)
        {
            SnapPicture();
        }

        //截取图像实现方法
        private void SnapPicture()
        {
            pictureBox1.Image = null;
            int count = mScreenInfos.Count();

            for (int i = 0; i < count; i++)
            {
                ScreenInfo si = mScreenInfos[i];
                si.Video.Visible = false;
                if (si.LoginId > 0)
                {
                    if (!System.IO.Directory.Exists("CutImage"))
                    {
                        System.IO.Directory.CreateDirectory("CutImage");
                    }
                    si.ImageFileName = "CutImage\\" + i + ".jpg";

                    bool isSuccess = CameraDevice.GT_DEV_CapturePicture(si.RealPlayId, si.ImageFileName);

                    if (!isSuccess)
                    {
                        throw new Exception("生成图片失败: " + si.IPAddress);
                    }
                }
            }

            vedioPic1.Visible = true;
            vedioPic2.Visible = true;
            vedioPic3.Visible = true;
            vedioPic4.Visible = true;
            vedioPic5.Visible = true;
            ImageSlear();
        }

        //拼接截取之后的图像
        private void ImageSlear()
        {
            int sleepTotal = 0;

            IList<Image> imageList = new List<Image>();
            int singleWidth = 0;
            int singleHeight = 0;
            foreach (ScreenInfo si in mScreenInfos)
            {
                while (!File.Exists(si.ImageFileName))
                {
                    Thread.Sleep(500);
                    sleepTotal += 500;

                    if (sleepTotal >= 3000)
                    {
                        throw new Exception("图片生成失败:" + si.IPAddress);
                    }

                }

                Bitmap Bi = (Bitmap)Bitmap.FromFile(si.ImageFileName);
                singleWidth = Bi.Width;
                singleHeight = Bi.Height;
                ShowSinglePic(Bi, singleWidth, singleHeight, si.ImageFileName);
                int nheight = (int)(Bi.Height - Bi.Height * ScreenInfo.UpLineLimit / 100 - Bi.Height * ScreenInfo.DownLineLimit / 100);
                int LX = 0;
                int LY = (int)(Bi.Height * ScreenInfo.UpLineLimit / 100);
                Bitmap CBi = ImageCut(Bi, LX, LY, Bi.Width, nheight);
                Bi.Dispose();
                if (CBi != null)
                {
                    Image img = CBi;
                    //img.RotateFlip(RotateFlipType.Rotate270FlipNone);
                    imageList.Add(img);
                }
                strHeadImagePath = "";
            }



            //横向拼接
            int width = 0;
            //策画总长度
            foreach (Image i in imageList)
            {
                width += i.Width;
            }
            //高度不变,按照比例来计算
            int height = imageList.Max(x => x.Height);
            //机关终极的图片白板
            Bitmap tableChartImage = new Bitmap(width, height);
            Graphics graph = Graphics.FromImage(tableChartImage);
            //初始化这个大图
            graph.DrawImage(tableChartImage, width, height);
            //初始化当前宽
            int currentWidth = 0;
            ////清除画布,背景设置为白色
            graph.Clear(System.Drawing.Color.White);

            foreach (Image i in imageList)
            {
                //拼图
                graph.DrawImage(i, currentWidth, 0);
                //拼接改图后,当前宽度
                currentWidth += i.Width;
                i.Dispose();
            }
            //对图像进行缩放，适应打印机打印
            Bitmap resizeImage = ResizeImage(tableChartImage, tableChartImage.Width / ScreenInfo.ReSizeScale, tableChartImage.Height / ScreenInfo.ReSizeScale);

            pictureBox1.Image = resizeImage;
            //删除摄像头截图是保存的原始图片
            foreach (ScreenInfo si in mScreenInfos)
            {
                if (File.Exists(si.ImageFileName))
                {
                    File.Delete(si.ImageFileName);
                }
            }


            //pictureBox1.Image = new System.Drawing.Bitmap(tableChartImage, pictureBox1.Width, pictureBox1.Height);
            //调用windows图片查看器打开
            //string filename = "slearImg.jpg";
            //tableChartImage.Save(filename);
            //System.Diagnostics.Process process = new System.Diagnostics.Process();
            //process.StartInfo.FileName = AppDomain.CurrentDomain.SetupInformation.ApplicationBase + filename;
            //process.StartInfo.Arguments = "rundll32.exe C://WINDOWS//system32//shimgvw.dll,ImageView_Fullscreen";
            //process.StartInfo.UseShellExecute = true;
            //process.Start();
            //process.Close();
        }

        private void ShowSinglePic(Bitmap bmp, int newH, int newW, string fileName)
        {
            Bitmap b = new Bitmap(newW, newH);
            Graphics g = Graphics.FromImage(b);
            g.InterpolationMode = InterpolationMode.HighQualityBicubic;
            bmp.RotateFlip(RotateFlipType.Rotate270FlipNone);
            g.DrawImage(bmp, new Rectangle(0, 0, newW, newH), new Rectangle(0, 0, newW, newH), GraphicsUnit.Pixel);
            if (fileName == "CutImage\\0.jpg")
            {
                vedioPic1.Image = b;
            }
            else
                if (fileName == "CutImage\\1.jpg")
                {
                    vedioPic2.Image = b;
                }
                else
                    if (fileName == "CutImage\\2.jpg")
                    {
                        vedioPic3.Image = b;
                    }
                    else
                        if (fileName == "CutImage\\3.jpg")
                        {
                            vedioPic4.Image = b;
                        }
                        else
                        {
                            vedioPic5.Image = b;
                        }
            g.Dispose();
        }

        //拼接好的图像进行缩放
        private Bitmap ResizeImage(Bitmap bmp, int newW, int newH)
        {
            try
            {
                Bitmap b = new Bitmap(newW, newH);
                Graphics g = Graphics.FromImage(b);
                // 插值算法的质量
                g.InterpolationMode = InterpolationMode.HighQualityBicubic;
                g.DrawImage(bmp, new Rectangle(0, 0, newW, newH), new Rectangle(0, 0, bmp.Width, bmp.Height), GraphicsUnit.Pixel);
                g.Dispose();
                return b;
            }
            catch
            {
                return null;
            }
        }

        //裁剪原始图像
        private Bitmap ImageCut(Bitmap b, int StartX, int StartY, int iWidth, int iHeight)
        {
            if (b == null)
            {
                return null;
            }
            int w = b.Width;
            int h = b.Height;
            if (StartX >= w || StartY >= h)
            {
                return null;
            }
            if (StartX + iWidth > w)
            {
                iWidth = w - StartX;
            }
            if (StartY + iHeight > h)
            {
                iHeight = h - StartY;
            }
            try
            {
                Bitmap bmpOut = new Bitmap(iWidth, iHeight, PixelFormat.Format24bppRgb);
                Graphics g = Graphics.FromImage(bmpOut);
                g.DrawImage(b, new Rectangle(0, 0, iWidth, iHeight), new Rectangle(StartX, StartY, iWidth, iHeight), GraphicsUnit.Pixel);
                g.Dispose();
                return bmpOut;
            }
            catch
            {
                return null;
            }
        }

        //保存按钮事件
        private void btnSave_Click(object sender, EventArgs e)
        {
            if (pictureBox1.Image == null)
            {
                MessageBox.Show("图片获取失败，请重新拍照 ！");
            }
            else
            {
                saveFileDialogLiu.Title = "另存为对话框";//对话框标题
                saveFileDialogLiu.InitialDirectory = "C:\\";//对话框初始目录
                saveFileDialogLiu.Filter = "JPG文件|*.jpg|BMP文件|*.bmp";

                //最后就是现实这个对话框,然后如果按了保存,则进行文件保存到指定目录：
                if (saveFileDialogLiu.ShowDialog() == DialogResult.OK)
                {
                    pictureBox1.Image.Save(saveFileDialogLiu.FileName);
                }
            }
        }
        //打印按钮事件
        private void btnPrint_Click(object sender, EventArgs e)
        {
            if (pictureBox1.Image == null)
            {
                MessageBox.Show("图片获取失败，请重新拍照 ！");
            }
            else
            {
                PrintDialog MyPrintDg = new PrintDialog();
                MyPrintDg.Document = printDocument1;
                if (MyPrintDg.ShowDialog() == DialogResult.OK)
                {
                    try
                    {
                        printDocument1.Print();
                    }
                    catch
                    {   //停止打印
                        printDocument1.PrintController.OnEndPrint(printDocument1, new System.Drawing.Printing.PrintEventArgs());
                    }
                }
            }
        }
        //打印控制页
        private void printDocument1_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
        {
            e.Graphics.DrawImage(pictureBox1.Image, 20, 20);
        }

        //上边界向下调位按钮事件
        private void btnUpLineDown_Click(object sender, EventArgs e)
        {
            uppanelline.Location = new Point(uppanelline.Location.X, uppanelline.Location.Y + 1);
            btnUpLineUp.Location = new Point(btnUpLineUp.Location.X, btnUpLineUp.Location.Y + 1);
            btnUpLineDown.Location = new Point(btnUpLineDown.Location.X, btnUpLineDown.Location.Y + 1);
        }
        //下边界向下调位按钮事件
        private void btnDownLineDown_Click(object sender, EventArgs e)
        {
            downpanelline.Location = new Point(downpanelline.Location.X, downpanelline.Location.Y + 1);
            btnDownLineUp.Location = new Point(btnDownLineUp.Location.X, btnDownLineUp.Location.Y + 1);
            btnDownLineDown.Location = new Point(btnDownLineDown.Location.X, btnDownLineDown.Location.Y + 1);
        }
        //下边界向上调位按钮事件
        private void btnDownLineUp_Click(object sender, EventArgs e)
        {
            downpanelline.Location = new Point(downpanelline.Location.X, downpanelline.Location.Y - 1);
            btnDownLineUp.Location = new Point(btnDownLineUp.Location.X, btnDownLineUp.Location.Y - 1);
            btnDownLineDown.Location = new Point(btnDownLineDown.Location.X, btnDownLineDown.Location.Y - 1);
        }
        //上边界向上调位按钮事件
        private void btnUpLineUp_Click(object sender, EventArgs e)
        {
            uppanelline.Location = new Point(uppanelline.Location.X, uppanelline.Location.Y - 1);
            btnUpLineUp.Location = new Point(btnUpLineUp.Location.X, btnUpLineUp.Location.Y - 1);
            btnUpLineDown.Location = new Point(btnUpLineDown.Location.X, btnUpLineDown.Location.Y - 1);
        }
        //保存基本参数配置按钮事件
        private void btnSaveParam_Click(object sender, EventArgs e)
        {
            string uplimit = ((uppanelline.Location.Y - toolStrip1.Height) * 100 / panelScreen.Size.Height + 1).ToString("0.00");
            string downlimit = ((panelScreen.Size.Height + toolStrip1.Height - downpanelline.Location.Y) * 100 / panelScreen.Size.Height + 1).ToString("0.00");
            ScreenInfo.UpdateCutParameter(uplimit, downlimit);
        }
        //退出窗体事件
        private void btnExit_Click(object sender, EventArgs e)
        {
            DialogResult dr = MessageBox.Show(this, "確定退出？", "退出主程序", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
            if (dr != DialogResult.Yes)
            {
                this.Close();
            }
        }

        private void btnRedo_Click(object sender, EventArgs e)
        {
            vedioPic1.Image = null;
            vedioPic2.Image = null;
            vedioPic3.Image = null;
            vedioPic4.Image = null;
            vedioPic5.Image = null;
            vedioPic1.Visible = false;
            vedioPic2.Visible = false;
            vedioPic3.Visible = false;
            vedioPic4.Visible = false;
            vedioPic5.Visible = false;
            pictureBox1.Image = null;
            int count = mScreenInfos.Count();

            for (int i = 0; i < count; i++)
            {
                ScreenInfo si = mScreenInfos[i];
                si.Video.Visible = true;
            }
        } 
    }
}
